# -*- coding: utf-8 -*-
# @Time    : 2025/8/12 10:19
# @Author  : FuKai ZHANG
# @File    : llm_client.py
# @Description :
import json
import requests
import yaml


def generate_test_cases_with_llm(op_info, api_key, endpoint, model):
    """
    构造提示词，调用 DeepSeek 大模型生成测试用例。
    """
    # 构造提示词
    prompt = f"""
    你是一个专业的 API 测试工程师。根据以下接口定义，生成接口测试用例（至少考虑3个方面：正向、负向、边界）。
    每个用例必须严格符合 YAML 格式：（单条测试用例的结构是{'caseID': casedata},casedata={'url': '/xxxxx',......}）
    caseID: # 动态生成，使用包含接口名称和用例编号，如 login_001
        url: # API 路径，相对于 host，以 / 开头
        method: # HTTP 方法，如 GET
        detail: # 测试用例描述，非空
        headers: # 请求头，键值对，非空（至少包含 Content-Type 如果适用）
        requestType: # params|form|json|file|null，非空
        data: # 请求参数，键值对，可空
        expected: # 预期响应，至少包含 statusCode
        extract: # 变量提取，可空

    以接口名称命名yaml文件，一个文件内包含多个接口用例

    接口定义：
    - Path: {op_info['path']}
    - Method: {op_info['method']}
    - Summary: {op_info['summary']}
    - Parameters: {json.dumps(op_info['parameters'], ensure_ascii=False)}
    - Request Body: {json.dumps(op_info['requestBody'], ensure_ascii=False)}
    - Responses: {json.dumps(op_info['responses'], ensure_ascii=False)}
    - Security: {json.dumps(op_info.get('security', []), ensure_ascii=False)}
    - Security Definitions: {json.dumps(op_info.get('security_definitions', {}), ensure_ascii=False)}

    特别注意：
    1. 如果是登录接口（根据接口路径、方法和响应结构判断），请在extract字段中提取token，例如：token: $.token 或者根据响应结构提取token
    2. 如果接口需要认证（通过security字段判断），请在headers中添加认证信息，如：Authorization: Bearer {{token}}
    3. 登录接口需要生成正向、负向和边界值测试用例
    4. 认证方案参考security_definitions中的定义，例如Bearer类型需要在Authorization头中添加"Bearer {{token}}"格式的值

    只输出纯 YAML 内容，不要添加额外文本。
    """

    # 调用 API
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    data = {
        "model": model,
        "messages": [{"role": "user", "content": prompt}],
        "temperature": 0.7,
        "max_tokens": 2048
    }
    try:
        response = requests.post(endpoint, headers=headers, json=data)
        response.raise_for_status()
        result = response.json()
        generated_yaml = result['choices'][0]['message']['content'].strip()
        # 验证生成的 YAML
        yaml.safe_load(generated_yaml)
        return generated_yaml
    except Exception as e:
        raise ValueError(f"调用大模型失败: {e}")